
let charaters = {
    gz : {
        name: "lv90公子", 
        base: 301,
        criticalRate: 5,
        criticalStrike: 50,
        dmgRate: 28.8
    }
}

let weapons = {
    tk: {
        name:"lv90天空弓",  // 每两秒 一次 1.25 * 攻击力 物理伤害
        base: 674,
        criticalRate: 22.1,
        criticalStrike:40
    },
    gongzang: {
        name:"lv90弓藏",  // 80增伤
        base: 510,
        attRate:41.3
    },
    juexian: {
        name:"lv90绝弦",  // 48大招增伤,
        base: 510,
        dmgRate:48,
        "精通":165
    }
}
let normal_clips = calc_clips_normal();
let normal_clips2 = calc_clips_normal(2);
let charactersDmg = []
charactersDmg.push(getDMG([charaters.gz,weapons.gongzang,{fixedAtt:311,criticalRate:31.1,dmgRate:46.6,attRate:46.6},normal_clips], (data,second) => {
    // 水4
    data.dmgRate += 15;
    let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
    let rea = { 精通:data.精通, 系数:2, 精通增伤:0 };

    let qdmg = getDmgDps(data, 8.35 + 2.16) * q(10) * df(90,90);
    let qdmgRea = getDmgDps(data, 8.35 + 2.16,rea) * q(10) * df(90,90);
    let edmg = getDmgDps(data, 1.3) * q(10) * df(90,90);
    data.dmgRate += 110;
    let eadmg = getDmgDps(data, 0.768+0.823+1.114+1.185+1.093+1.19+1.423+1.19*2) * q(10) * df(90,90);
    let ret = qdmgRea + edmg + eadmg*4 + 7 * attack*1.25*0.45;
    return {point:ret, data, second, edmg,qdmg,qdmgRea,eadmg,attack}
}))
// gz tk
charactersDmg.push(getDMG([charaters.gz,weapons.tk,{fixedAtt:311,criticalStrike:62.2,dmgRate:46.6,attRate:46.6},normal_clips2], (data,second) => {
    // 水4
    data.dmgRate += 15;
    let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
    let rea = { 精通:data.精通, 系数:2, 精通增伤:0 };

    let qdmg = getDmgDps(data, 8.35 + 2.16) * q(10) * df(90,90);
    let qdmgRea = getDmgDps(data, 8.35 + 2.16,rea) * q(10) * df(90,90);
    let edmg = getDmgDps(data, 1.3) * q(10) * df(90,90);
    data.dmgRate += 30;
    let eadmg = getDmgDps(data, 0.768+0.823+1.114+1.185+1.093+1.19+1.423+1.19*2) * q(10) * df(90,90);
    let ret = qdmgRea + edmg + eadmg*4 + 7 * attack*1.25*0.45;
    return {point:ret, data, second, edmg,qdmg,qdmgRea,eadmg,attack}
}))

let qH = [];
Object.values(weapons).forEach(w => {
    qH.push(getDMG([charaters.gz,w,{fixedAtt:311,criticalStrike:62.2,attRate:46.6,dmgRate:46.6},normal_clips2], (data,second) => {
        // 乐团 宗室
        data.dmgRate += 20;
        data.精通 += 80;

        // 班尼特 1000攻击力 20宗室 48讨龙 莫娜砂糖增伤70 风套40减抗 砂糖加精通300
        data.fixedAtt += 1000;
        data.attRate += 68;
        data.dmgRate += 70;
        data.精通 += 300;
        data.criticalStrike += 120;  // 深渊加成 深渊buff没考虑
        
        let attack = data.base *(1 + data.attRate/100) + data.fixedAtt
        let rea = { 精通:data.精通, 系数:2, 精通增伤:0 };
    
        let qdmgRea = getDmgDps({...data,criticalRate:100}, 9.86,rea) * q(-30) * df(90,90);
        let ret = qdmgRea 
        return {point:ret, data, second, qdmgRea,attack}
    }))
})

console.log(charactersDmg.sort((a,b)=>b.point-a.point));
// console.log(qH.sort((a,b)=>b.point-a.point));

function getDMG(dataarr, getRet){
    let chance = 25;
    let _ret = [];
    for (let index = 0; index <= chance; index++) {
        let criticalStrike = index; 
        for (let index2 = 0; index2 <= chance - index; index2++) {
            let criticalRate = index2;
            for (let index3 = 0; index3 <= chance-index-index2; index3++) {
                let attRate = index3;
                let defenceRate = chance - index - index2 - index3;
                _ret.push({
                    精通: 23 * defenceRate,
                    attRate:5.8 * attRate,
                    criticalRate:3.9 * criticalRate,
                    criticalStrike:7.8 * criticalStrike
                });
            }
        }
    }
    _ret = _ret.map(second => {
        let panel = getPanel([...dataarr, second]);
        return  getRet(panel, second)
    })
    _ret.sort((b,a)=> a.point-b.point)
    return _ret[0]
}

function getDmgDps(data, rate=1, rea){
    let criticalRate = data.criticalRate
    if(criticalRate > 100){criticalRate = 100}
    let baseat = data.base * (1 + data.attRate/100) + data.fixedAtt;
    let bdmg = baseat * (1 + data.criticalStrike/100);
    let bdps = (criticalRate * 10 * bdmg + (1000-criticalRate * 10)*baseat)/1000
    let adddmg = bdps * (1 + data.dmgRate/100)
    if(rea){
        let {精通, 系数, 精通增伤} = rea
        let tmp = 1 + 精通增伤 + jt(精通);
        return adddmg * rate * 系数 * tmp
    }
    return adddmg * rate
}

function getPanel(arr){
    let info = {name1:"",name2:""};
    arr.forEach((item, i)=>{
        if(item.name){
            info["name" + (i+1)] = item.name
        }
        for (const key in item) {
            if(key !== "name"){
                if(info[key]){
                    info[key] += item[key]
                } else {
                    info[key] = item[key]
                }
            }
        }
    })
    return info
}

function q (resistance) {
    if(resistance < 0) {
        return 1 - resistance/200
    } else if (resistance >=0 && resistance < 75){
        return 1 - resistance/100
    } else {
        return 1/(1+resistance/100*4)
    }
}

function df(youLv=0, eLv=0, td){
    return (100+youLv)/(100+youLv+(100+eLv)*(td? (100-td)/100 : 1))
}

// 固定攻击力 19  防御力23 生命值299 5.3% 
function calc_clips_normal (n) {
    let clips = [
        {
            精通:23,
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            精通:23,
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            attRate: 5.8,
            fixedAtt:19,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            精通:23,
            attRate: 5.8,
            criticalRate: 3.9,
            criticalStrike:7.8
        },
        {
            精通:23,
            attRate: 5.8,
            criticalRate:n!=2? 0:3.9,
            criticalStrike:n!=2? 7.8:0
        }
    ]
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}

function jt(k){
    return Math.log(0.99316499 + 0.00209988607 * k + 0.0000001213236971*k*k)
}